Ensure we rerender after a suspensefully hydrating boundary throws an…#4856
Merged
JoviDeCroock merged 2 commits intov10.xfrom Jul 28, 2025
Merged
Ensure we rerender after a suspensefully hydrating boundary throws an…#4856JoviDeCroock merged 2 commits intov10.xfrom
JoviDeCroock merged 2 commits intov10.xfrom
Conversation
📊 Tachometer Benchmark ResultsSummaryA summary of the benchmark results will show here once they finish. ResultsThe full results of your benchmarks will show here once they finish. |
|
Size Change: +221 B (+0.28%) Total Size: 78.9 kB
ℹ️ View Unchanged
|
b8fee2d to
c56d363
Compare
c56d363 to
dec937f
Compare
JoviDeCroock
commented
Jul 28, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Consider the following scenario, we have an application with a shell:
We server-side render the HTML, send it to the client. The client starts hydrating and we do that successfully up to the
Body, theBodywill throw a Promise and we'll suspend. This means that the Header/Footer will be interactive the the Body won't be, when Body loads we continue hydration but there is an error in the component.When there is an error we remove the existing DOM as hydration is considered useless and we need to render the
ErrorBoundary. When theErrorBoundaryis set toretryimmediately we'll attempt to re-render the component. With Signals (and PureComponent/...) there's a chance that we now bail out of rendering, we'd bail out of rendering while having a partially mutated oldVNode. The oldVNode would signal that it has_componentand hence is not new while being absent from_childrenas we never reacheddiffChildren.This PR will ensure that when we error that we must consider the update as forced, this ensures that we never bail out of rendering and that any erroneous state that could be in the component is reset.
Initially I had a simpler solution where I would set
vnode._componentto null but that means that we'd break components catching their own error. Hence why I got to a solution that requires a bit more bytes but solves most of the issues. In reality theelsebranch isn't really needed for the issue at hand but I'd prefer being safe.Big thanks to @joel-solymosi for finding this issue and providing the hints we needed.
The issue was introduced in #4563
Supersedes #4854
Supersedes #4822